{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### ICS 104 - Introduction to Programming in Python and C  \n",
    "# Objects and Classes\n",
    "## Reading Assignment\n",
    "- Chapter 9: Sections 1 - 7."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "# Learning Outcomes\n",
    "- To understand the concepts of classes, objects and encapsulation. \n",
    "- To implement instance variables, methods and constructors.\n",
    "- To be able to design, implement and test your own classes."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Object-Oriented Programming\n",
    "- You have learned how to structure your programs by decomposing tasks into functions.\n",
    "    - Breaking tasks into subtasks\n",
    "    - Writing re-usable methods to handle tasks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- We will now study Objects and Classes\n",
    "    - To build larger and more complex programs\n",
    "    - To model objects we use in the world"
   ]
  },
  {
   "attachments": {
    "ch09fig1.PNG": {
     "image/png": "[encoded data, 1337140 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Classes\n",
    "- A <font color='blue'>**class**</font> describes objects with the same behavior. \n",
    "- For example, a Car class describes all passenger vehicles that have a certain capacity and shape. \n",
    "![ch09fig1.PNG](attachment:ch09fig1.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Objects and Programs\n",
    "- You have learned how to structure your programs by decomposing tasks into functions\n",
    "    - Experience shows that it does not go far enough\n",
    "    - It is difficult to understand and update a program that consists of a large collection of functions. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- To overcome this problem, computer scientists invented <font color='blue'>**object-oriented programming**</font>, a programming style in which tasks are solved by collaborating objects.\n",
    "- Each object has its own set of data, together with a set of methods that act upon the data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- You have already experienced this programming style when you used strings, lists, and file objects. \n",
    "- Each of these objects has a set of methods. \n",
    "    - For example, you can use the insert or remove methods to operate on list objects."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Python Classes\n",
    "- A class describes a set of objects with the same behavior.\n",
    "    - For example, the `str` class describes the behavior of all strings\n",
    "    - This class specifies how a string stores its characters, which methods can be used with strings, and how the methods are implemented. \n",
    "    - For example, when you have a `str` object, you can invoke the upper method: "
   ]
  },
  {
   "attachments": {
    "ch09fig2.PNG": {
     "image/png": "[encoded data, 14168 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig2.PNG](attachment:ch09fig2.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "- In contrast, the list class describes the behavior of objects that can be used to store a collection of values\n",
    "- This class has a different set of methods"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- For example, the following call would be illegal - the list class has no upper() method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "[\"Hello\", \"World\"].upper()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- However, list has a pop() method, and the following call is legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "[\"Hello\", \"World\"].pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "myList = [\"Hello\", \"World\"]\n",
    "myList.pop()\n",
    "print(myList)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Student Activity\n",
    "- Is the method call \"Hello World\".print() legal? Why or Why not?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "\"Hello World!\".print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Public Interfaces\n",
    "- The set of all methods provided by a class, together with a description of their behavior, is called the public interface of the class\n",
    "- When you work with an object of a class, you do not know how the object stores its data, or how the methods are implemented\n",
    "    - You need not know how a `str` object organizes a character sequence, or how a list stores its elements\n",
    "- All you need to know is the public interface – which methods you can apply, and what these methods do"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- The process of providing a public interface, while hiding the implementation details, is called <font color='blue'>**encapsulation**</font>\n",
    "- If you work on a program that is being developed over a long period of time, it is common for implementation details to change, usually to make objects more efficient or more capable\n",
    "    - When the implementation is hidden, the improvements do not affect the programmers who use the objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Implementing a Simple Class\n",
    "- Consider, <font color='blue'>**Tally Counter:**</font> A class that models a mechanical device that is used to count people\n",
    "    - For example, to find out how many people board a bus.\n",
    "- Whenever the operator pushes a button, the counter value advances by one. The counter has a display to show the current value."
   ]
  },
  {
   "attachments": {
    "ch09fig5.PNG": {
     "image/png": "[encoded data, 313880 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "![ch09fig5.PNG](attachment:ch09fig5.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- What **operations** (aka methods) can you identify are needed in this class?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "-    \n",
    "    - Increment the tally\n",
    "    - Get the current total"
   ]
  },
  {
   "attachments": {
    "ch09fig6.PNG": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Using the Counter Class\n",
    "- First, note that we will show how to define the class later. Now, we are concerned with using the class. \n",
    "- First, we construct an object of the class.\n",
    "- In Python, you don’t explicitly declare instance variables\n",
    "    - Did we declare an integer variable before using it?\n",
    "- Instead, when one first assigns a value to an instance variable, that instance variable is created\n",
    "![ch09fig6.PNG](attachment:ch09fig6.PNG)\n",
    "- More information about constructing objects will be given later."
   ]
  },
  {
   "attachments": {
    "ch09fig7.PNG": {
     "image/png": "[encoded data, 18652 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- Next, we invoke methods on our object\n",
    "![ch09fig7.PNG](attachment:ch09fig7.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- We can invoke the methods again, and the result will be different:  \n",
    "```\n",
    "   tally.click()\n",
    "   result = tally.getValue()     # Sets result to 3```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Instance Variables\n",
    "- An instance of a class is an object of the class\n",
    "- An object stores its data in <font color='blue'>**instance variables**</font>\n",
    "- In our example, each Counter object has a single instance variable named _value\n",
    "    - For example, if concertCounter and boardingCounter are two objects of the Counter class, then each object has its own _value variable"
   ]
  },
  {
   "attachments": {
    "ch09fig8.PNG": {
     "image/png": "[encoded data, 36268 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig8.PNG](attachment:ch09fig8.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- Instance variables are part of the implementation details that should be hidden from the user of the class\n",
    "    - With some programming languages an instance variable can only be accessed by the methods of its own class\n",
    "    - The Python language does not enforce this restriction\n",
    "    - However, the underscore indicates to class users that they should not directly access the instance variables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Class Methods\n",
    "- The methods provided by the class are defined in the class body\n",
    "- The click() method advances the _value instance variable by 1\n",
    "```\n",
    "   def click(self):  \n",
    "         self._value = self._value + 1```\n",
    "- A method definition is very similar to a function with these exceptions:\n",
    "    - A method is defined as part of a class definition\n",
    "    - The first parameter variable of a method is called self"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Class Methods and Attributes\n",
    "- Note how the click() method increments the instance variable _value \n",
    "- Which instance variable? The one belonging to the object on which the method is invoked\n",
    "    - In the example below the call to click() advances the _value variable of the concertCounter object \n",
    "    - No argument was provided when the click() method was called even though the definition includes the `self` parameter variable\n",
    "    - The `self` parameter variable refers to the object on which the method was invoked `concertCounter` in this example\n",
    "- ```concertCounter.click()```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Example of Encapsulation\n",
    "- The getValue() method returns the current `_value`:  \n",
    "```\n",
    "def getValue(self) :\n",
    "         return self._value```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- This method is provided so that users of the Counter class can find out how many times a particular counter has been clicked\n",
    "- A class user should not directly access any instance variables\n",
    "- Restricting access to instance variables is an essential part of encapsulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Complete Simple Class Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "#  This module defines the Counter class.\n",
    "#\n",
    "\n",
    "## Models a tally counter whose value can be \n",
    "#  incremented, viewed, or reset.\n",
    "#\n",
    "class Counter :   \n",
    "   ## Gets the current value of this counter.\n",
    "   #  @return the current value   \n",
    "   #\n",
    "   def getValue(self) :\n",
    "      return self._value\n",
    "\n",
    "   ## Advances the value of this counter by 1.\n",
    "   #\n",
    "   def click(self) :\n",
    "      self._value = self._value + 1\n",
    "\n",
    "   ## Resets the value of this counter to 0.\n",
    "   #\n",
    "   def reset(self) :\n",
    "      self._value = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "##\n",
    "#  This program demonstrates the Counter class.\n",
    "#\n",
    "\n",
    "# Import the Counter class from the counter module. \n",
    "#import counter\n",
    "#from counter import Counter\n",
    "# The above two lines are commented since we did not\n",
    "# save the Counter class in a file called counter.py. \n",
    "\n",
    "tally = Counter()\n",
    "tally.reset()\n",
    "tally.click()\n",
    "tally.click()\n",
    "\n",
    "result = tally.getValue()\n",
    "print(\"Value:\", result)\n",
    "\n",
    "tally.click()\n",
    "result = tally.getValue()\n",
    "print(\"Value:\", result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Student Activity\n",
    "- What would happen if you did not call reset immediately after constructing the tally object?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Public Interface of a Class\n",
    "-  When you design a class, start by specifying the public interface of the new class\n",
    "    - What tasks will this class perform?\n",
    "    - What methods will you need?\n",
    "    - What parameters will the methods need to receive?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Example Public Interface (A Cash Register Class)"
   ]
  },
  {
   "attachments": {
    "ch09fig9.PNG": {
     "image/png": "[encoded data, 549516 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig9.PNG](attachment:ch09fig9.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- We want to use objects that simulate cash registers. \n",
    "    - A cashier who rings up a sale presses a key to start the sale, then rings up each item. A display shows the amount owed as well as the total number of items purchased.\n",
    "    "
   ]
  },
  {
   "attachments": {
    "ch09fig10.PNG": {
     "image/png": "[encoded data, 35436 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig10.PNG](attachment:ch09fig10.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Writing the Public Interface"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "## A simulated cash register that tracks the item count and the total amount due.  \n",
    "#  \n",
    "class CashRegister:  \n",
    "    ## Adds an item to this cash register.  \n",
    "    # @param price the price of this item  \n",
    "    #  \n",
    "    def addItem(self, price):  \n",
    "        # Method body - The method declaration make up the public interface of the class  \n",
    "                   \n",
    "    ## Gets the price of all items in the current sale.  \n",
    "    # @return the total price  \n",
    "    #  \n",
    "    #def getTotal(self) :  \n",
    "        # The data and method bodies make up the private implementation of the class  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Using the Class\n",
    "- After defining the class we can now construct an object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "register1 = CashRegister()\n",
    "    # Constructs a CashRegister object"
   ]
  },
  {
   "attachments": {
    "ch09fig11.PNG": {
     "image/png": "[encoded data, 47092 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig11.PNG](attachment:ch09fig11.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Using Methods\n",
    "- Now that an object has been constructed, we are ready to invoke a method:\n",
    "- ```register1.addItem(1.95) # Invokes a method```"
   ]
  },
  {
   "attachments": {
    "ch09fig11-1.PNG": {
     "image/png": "[encoded data, 88360 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Instance Variables of Objects\n",
    "- Each object of a class has a separate set of instance variables\n",
    "![ch09fig11-1.PNG](attachment:ch09fig11-1.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Constructors\n",
    "- A constructor is a method that initializes instance variable of an object. \n",
    "    - It is automatically called when an object is created.\n",
    "    - Python uses the special name `__init__` to define constructor."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "```  \n",
    "  \n",
    "# Calling a method that matches the name of the class  \n",
    "   \n",
    "# Invokes the constructor  \n",
    "\n",
    "def __init__(self):  \n",
    "\n",
    "    self._itemCount = 0  \n",
    "    \n",
    "    self._totalPrice = 0.0  \n",
    "#```      "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Default and Named Arguments\n",
    "- Only one constructor can be defined per class:\n",
    "- But you can define constructor with default argument values that simulate multiple definitions   \n",
    "```   \n",
    "   class BankAccount:  \n",
    "           def __int__(self, initialBlance = 0.0):  \n",
    "                 self._balance = initialBalance```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- If no value is passed to the constructor when a BankAccount object is created the default value will be used    \n",
    "```  \n",
    "  joesAccount = BankAccount() # Balance is set to 0```"
   ]
  },
  {
   "attachments": {
    "ch09fig12.PNG": {
     "image/png": "[encoded data, 124092 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Syntax: Constructors\n",
    "![ch09fig12.PNG](attachment:ch09fig12.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Constructors: `self`\n",
    "- The first parameter variable of every constructor must be self\n",
    "- When the constructor is invoked to construct a new object, the self parameter variable is set to the object that is being initialized"
   ]
  },
  {
   "attachments": {
    "ch09fig13.PNG": {
     "image/png": "[encoded data, 32880 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig13.PNG](attachment:ch09fig13.PNG)"
   ]
  },
  {
   "attachments": {
    "ch09fig14.PNG": {
     "image/png": "[encoded data, 37952 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Object References\n",
    "![ch09fig14.PNG](attachment:ch09fig14.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Syntax: Instance Methods\n",
    "- Use instance variables inside methods of the class\n",
    "    - Similar to the constructor, all other instance methods must include the `self` parameter as the fist parameter\n",
    "    - You must specify the `self` implicit parameter when using instance variable inside the class"
   ]
  },
  {
   "attachments": {
    "ch09fig15.PNG": {
     "image/png": "[encoded data, 104880 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig15.PNG](attachment:ch09fig15.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Invoking Instance Methods\n",
    "- As with the constructor, every method must include the special `self` parameter variable, and it must be listed first. \n",
    "- When a method is called, a reference to the object on which the method was invoked (register1) is automatically passed to the self parameter variable: "
   ]
  },
  {
   "attachments": {
    "ch09fig16.PNG": {
     "image/png": "[encoded data, 11536 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "![ch09fig16.PNG](attachment:ch09fig16.PNG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Complete Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "#  This module defines the CashRegister class.\n",
    "## A simulated cash register that tracks the item \n",
    "#  count and the total amount due.\n",
    "\n",
    "class CashRegister :\n",
    "   ## Constructs a cash register with cleared item \n",
    "   #  count and total.\n",
    "   #\n",
    "   def __init__(self) :\n",
    "      self._itemCount = 0\n",
    "      self._totalPrice = 0.0\n",
    "      \n",
    "   ## Adds an item to this cash register.\n",
    "   #  @param price the price of this item\n",
    "   #\n",
    "   def addItem(self, price) :\n",
    "      self._itemCount = self._itemCount + 1\n",
    "      self._totalPrice = self._totalPrice + price \n",
    "      \n",
    "   ## Gets the price of all items in the current \n",
    "   # sale.\n",
    "   #  @return the total price\n",
    "   #\n",
    "   def getTotal(self) :\n",
    "      return self._totalPrice\n",
    "      \n",
    "   ## Gets the number of items in the current sale.\n",
    "   #  @return the item count\n",
    "   #\n",
    "   def getCount(self) :\n",
    "      return self._itemCount\n",
    "\n",
    "   ## Clears the item count and the total.\n",
    "   #  \n",
    "   def clear(self) :\n",
    "      self._itemCount = 0\n",
    "      self._totalPrice = 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "split",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "## \n",
    "#  This program tests the CashRegister class.\n",
    "#\n",
    "\n",
    "#from cashregister import CashRegister\n",
    "\n",
    "register1 = CashRegister()\n",
    "register1.addItem(1.95)\n",
    "register1.addItem(0.95)\n",
    "register1.addItem(2.50)\n",
    "print(register1.getCount())\n",
    "print(\"Expected: 3\")\n",
    "print(\"%.2f\" % register1.getTotal())\n",
    "print(\"Expected: 5.40\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Summary\n",
    "- A class describes a set of objects with the same behavior\n",
    "    - Every class has a public interface: a collection of methods through which the objects of the class can be manipulated\n",
    "    - Encapsulation is the act of providing a public interface and hiding the implementation details\n",
    "    - Encapsulation enables changes in the implementation without affecting users of a class"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "- An object’s instance variables store the data required for executing its methods\n",
    "- Each object of a class has its own set of instance variables\n",
    "- An instance method can access the instance variables of the object on which it acts\n",
    "- A private instance variable should only be accessed by the methods of its own class\n",
    "- Class variables have a single copy of the variable shared among all of the instances of the class"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "cell_style": "center",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- A constructor initializes the object’s instance variables \n",
    "- A constructor is invoked when an object is created\n",
    "- The constructor is defined using the special method name: _ _init_ _()\n",
    "- Default arguments can be used with a constructor to provide different ways of creating an object"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "rise": {
   "theme": "yellow"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
